package com.yisu.expressway.utils;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Environment;
import android.view.View;

import com.bm.library.Info;
import com.yisu.expressway.application.ExApplication;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class BitmapUtil
{

	public static final int AVATAR_IMAGE_LENGTH = 750;
	private final static int TARGET_MIN_PIXEL = 500;//短边像素临界值为500px

	private static float CROP_RATE = 1.42f;

	private static Info mImgInfo;

	/**
	 * Compress bitmap in case of out of memory. Any device's OS of which VERSION.SDK_INT < 11 suggested return a smaller image.
	 * @param srcPath Image source path from local.
	 * @param targetWidth The image width after compressed.
	 * @param targetHeight The image height after compressed.
	 * @return compressed bitmap
	 */
	public static Bitmap getImage(String srcPath, int targetWidth, int targetHeight)
	{
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		newOpts.inPurgeable = true;
		newOpts.inInputShareable = true;
		newOpts.inPreferredConfig = Config.RGB_565;
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

		newOpts.inJustDecodeBounds = false;
		int old_w = newOpts.outWidth;
		int old_h = newOpts.outHeight;
		int new_w = targetWidth;
		int new_h = targetHeight;

		int be = 1;
		if (0 != new_w && 0 != new_h)
		{
			be = (old_w / new_w + old_h / new_h) >> 1;
			if (be < 1)
			{
				be = 1;
			}
		}

		if (1 == be && DisplayUtil.getScreenWidth(ExApplication.getInstance().getApplicationContext()) < 480)
		{
			be = 2;
		}
		newOpts.inSampleSize = be;
		bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
		return bitmap;
	}


	/**
	 * Compress bitmap in case of out of memory. Any device's OS of which VERSION.SDK_INT < 11 suggested return a smaller image.
	 * @param srcPath Image source path from local.
	 * @param targetWidth The image width after compressed.
	 * @param targetHeight The image height after compressed.
	 * @param minInSampleSize If the original bitmap size is as big as the target size, the return is NO different from the original.
	 *  					  Set this value to force to compress, any value <= 1 is treated the same as 1.
	 * @return compressed bitmap
	 */
	public static Bitmap getImage(String srcPath, int targetWidth, int targetHeight, int minInSampleSize)
	{
		BitmapFactory.Options newOpts = new BitmapFactory.Options();
		newOpts.inPurgeable = true;
		newOpts.inInputShareable = true;
		newOpts.inPreferredConfig = Config.RGB_565;
		newOpts.inJustDecodeBounds = true;
		Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);

		newOpts.inJustDecodeBounds = false;
		int old_w = newOpts.outWidth;
		int old_h = newOpts.outHeight;
		int new_w = targetWidth;
		int new_h = targetHeight;

		int be = 1;
		if (0 != new_w && 0 != new_h)
		{
			be = (old_w / new_w + old_h / new_h) >> 1;
		}
		
		be = be > minInSampleSize ? be : minInSampleSize;
		if (be < 1)
		{
			be = 1;
		}

		newOpts.inSampleSize = be;
		bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
		return bitmap;
	}



	public static Bitmap getImgWithUrlAfterCompress(String imageUrl, int defaultInSampleSize, boolean isUseDefault, boolean isSetColorModel)
	{
		InputStream inputStream = null;
		Bitmap bitmap = null;

		try
		{
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inPurgeable = true;
			options.inInputShareable = true;

			if (isSetColorModel)
			{
				options.inPreferredConfig = Config.RGB_565;
			}
			//            options.inJustDecodeBounds = true;

			URL url = new URL(imageUrl);
			HttpURLConnection connection = (HttpURLConnection) url.openConnection();
			inputStream = connection.getInputStream();

			//            bitmap = BitmapFactory.decodeStream(inputStream, null, options);

			//            options.inJustDecodeBounds = false;

			if (isUseDefault)
			{
				options.inSampleSize = defaultInSampleSize;
			}
			else
			{
				int be = computeSampleSize(options, -1, 128 * 128); //解析图片所需的BitmapFactory.Options,调整后图片最小的宽或高值,调整后图片的内存占用量上限

				if (be <= 1 && defaultInSampleSize <= 1)
				{
					options.inSampleSize = 1;
				}
				else
				{
					options.inSampleSize = be > defaultInSampleSize ? be : defaultInSampleSize;
				}
			}

			bitmap = BitmapFactory.decodeStream(inputStream, null, options);
		}
		catch (Exception e)
		{
			HBLog.e("xr", "[BitmapUtil] getImgWithUrlAfterCompress Exception = " + e.toString());
		}
		finally
		{
			try
			{
				if (null != inputStream)
				{
					inputStream.close();
				}
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
		}
		return bitmap;
	}

	public static Bitmap getImgWithPathAfterCompress(String path, int defaultInSampleSize, boolean isUseDefault, boolean isSetColorModel)
	{
		Bitmap bitmap = null;

		try
		{
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inPurgeable = true;
			options.inInputShareable = true;

			if (isSetColorModel)
			{
				options.inPreferredConfig = Config.RGB_565;
			}
			//            options.inJustDecodeBounds = true;

			//            bitmap = BitmapFactory.decodeFile(path, options);

			//            options.inJustDecodeBounds = false;

			if (isUseDefault)
			{
				options.inSampleSize = defaultInSampleSize;
			}
			else
			{
				int be = computeSampleSize(options, -1, 128 * 128); //解析图片所需的BitmapFactory.Options,调整后图片最小的宽或高值,调整后图片的内存占用量上限

				if (be <= 1 && defaultInSampleSize <= 1)
				{
					options.inSampleSize = 1;
				}
				else
				{
					options.inSampleSize = be > defaultInSampleSize ? be : defaultInSampleSize;
				}
			}

			bitmap = BitmapFactory.decodeFile(path, options);
		}
		catch (Exception e)
		{
			HBLog.e("xr", "[BitmapUtil] getImgWithPathAfterCompress Exception = " + e.toString());
		}

		return bitmap;
	}

	public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels)
	{
		int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);

		int roundedSize;
		if (initialSize <= 8)
		{
			roundedSize = 1;
			while (roundedSize < initialSize)
			{
				roundedSize <<= 1;
			}
		}
		else
		{
			roundedSize = (initialSize + 7) / 8 * 8;
		}

		return roundedSize;
	}

	public static int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels)
	{
		double w = options.outWidth;
		double h = options.outHeight;

		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));

		if (upperBound < lowerBound)
		{
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}

		if ((maxNumOfPixels == -1) && (minSideLength == -1))
		{
			return 1;
		}
		else if (minSideLength == -1)
		{
			return lowerBound;
		}
		else
		{
			return upperBound;
		}
	}

	// It's supposed that length and width of the image is the same.
	public static String scalePictureBitmapForAvatar(String filename) {
		Bitmap bitmap = null;
		String path = "";
		String basePath = Environment.getExternalStorageDirectory() .getAbsolutePath();
		try {
			bitmap = BitmapFactory.decodeFile(filename);
			bitmap = CropBitmap(bitmap);
			int origLength = bitmap.getWidth();
			int targetLength = Math.min(origLength, AVATAR_IMAGE_LENGTH);
			bitmap = Bitmap.createScaledBitmap(bitmap, targetLength, targetLength, true);
			File file = new File(basePath+"/mocon");
			if (!file.exists())
				file.mkdir();

			file = new File(basePath+"/"+System.currentTimeMillis()+".jpg".trim());
			String fileName = file.getName();
			String mName = fileName.substring(0, fileName.lastIndexOf("."));
			String sName = fileName.substring(fileName.lastIndexOf("."));

			// /sdcard/myFolder/temp_cropped.jpg
			path = basePath+"/mocon" + "/" + mName + "_cropped" + sName;
			file = new File(path);
			try {
				file.createNewFile();
				FileOutputStream fos = new FileOutputStream(file);
				bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);
				fos.flush();
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return path;
	}

	public static String scalePictureBitmap(String filename,int maxwidth) {
		Bitmap bitmap = null;
		String path = "";
		String basePath = Environment.getExternalStorageDirectory() .getAbsolutePath();
		try {

			bitmap = BitmapFactory.decodeFile(filename);

            bitmap = CropBitmap(bitmap);

			int afterwidth = bitmap.getWidth();
			int afterheight = bitmap.getHeight();
			float con = 1.0f;
			int smaller = afterheight > afterwidth ? afterwidth :afterheight;
			if (smaller > TARGET_MIN_PIXEL) {
				con = (float) TARGET_MIN_PIXEL / smaller;
			}
			bitmap = Bitmap.createScaledBitmap(bitmap, (int) (con * afterwidth), (int) (con * afterheight), true);
			File file = new File(basePath+"/mocon");
			if (!file.exists())
				file.mkdir();

			file = new File(basePath+"/"+System.currentTimeMillis()+".jpg".trim());
			String fileName = file.getName();
			String mName = fileName.substring(0, fileName.lastIndexOf("."));
			String sName = fileName.substring(fileName.lastIndexOf("."));

			// /sdcard/myFolder/temp_cropped.jpg
			path = basePath+"/mocon" + "/" + mName + "_cropped" + sName;
			file = new File(path);
			try {
				file.createNewFile();
				FileOutputStream fos = new FileOutputStream(file);
				bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
				fos.flush();
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return path;
	}

	public static String compressBitmap(String filename) {
		Bitmap bitmap = null;
		String path = "";
		String basePath = Environment.getExternalStorageDirectory() .getAbsolutePath();
		try {

			bitmap = BitmapFactory.decodeFile(filename);

			int afterwidth = bitmap.getWidth();
			int afterheight = bitmap.getHeight();

			float con = 1.0f;

			bitmap = Bitmap.createScaledBitmap(bitmap, (int) (con * afterwidth), (int) (con * afterheight), true);
			File file = new File(basePath+"/mocon");
			if (!file.exists())
				file.mkdir();

			file = new File(basePath+"/"+System.currentTimeMillis()+".jpg".trim());
			String fileName = file.getName();
			String mName = fileName.substring(0, fileName.lastIndexOf("."));
			String sName = fileName.substring(fileName.lastIndexOf("."));

			// /sdcard/myFolder/temp_cropped.jpg
			path = basePath+"/mocon" + "/" + mName + "_cropped" + sName;
			file = new File(path);
			try {
				file.createNewFile();
				FileOutputStream fos = new FileOutputStream(file);
				bitmap.compress(Bitmap.CompressFormat.JPEG, 70, fos);
				fos.flush();
				fos.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return path;
	}

	private static Bitmap CropBitmap(Bitmap bitmap){
		Bitmap result = bitmap;
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		if(width == 0 || height == 0){
			return result;
		}

		int minLenth = Math.min(width,height);
		int maxLenth = Math.max(width,height);

		if((float)maxLenth / minLenth <= CROP_RATE){
			return result;
		}

		int targetLenth = (int)(minLenth * CROP_RATE);

		int startOffset = (maxLenth - targetLenth) / 2;
		int xTopLeft;
		int yTopLeft;
		int targetWidth;
		int targetHeight;

		if( height > width){
			xTopLeft = 0;
			yTopLeft = startOffset;
			targetWidth = minLenth;
			targetHeight = targetLenth;
		}else{
			xTopLeft = startOffset;
			yTopLeft = 0;
			targetWidth = targetLenth;
			targetHeight = minLenth;
		}

		try{
			result = Bitmap.createBitmap(bitmap, xTopLeft, yTopLeft, targetWidth, targetHeight);
		}
		catch(Exception e){

		}

		return result;

	}

	/**
	 * 裁剪成圆型bitmap
	 * @param bmp
	 * @return
	 */
	public static Bitmap circleBitmap(Bitmap bmp, int size) {

		/**如果为长方形则先剪裁成正方形**/
		int width = bmp.getWidth();
		int height = bmp.getHeight();
		if(height != width) {
			int minWidth = width > height ? height : width;

			int leftTopX = (width - minWidth) / 2;
			int leftTopY = (height - minWidth) / 2;

			bmp = Bitmap.createBitmap(bmp, leftTopX, leftTopY, minWidth, minWidth, null, false);
		}

		Bitmap output = Bitmap.createBitmap(size,
				size, Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final Paint paint = new Paint();
		final Rect destR = new Rect(0, 0, size, size);

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		int r = size / 2;
		canvas.drawCircle(r, r, r, paint);
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
		canvas.drawBitmap(bmp, null, destR, paint);
		return output;
	}


	/**
	 * 加载本地图片
	 * http://bbs.3gstdy.com
	 * @param url
	 * @return
	 */
	public static Bitmap getLoacalBitmap(String url) {
		try {
			FileInputStream fis = new FileInputStream(url);
			return BitmapFactory.decodeStream(fis);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
			return null;
		}
	}

	public static void startScale2Full(View v){

	}

}
